#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <chrono>
#include <sstream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>

using std::cout;
using std::endl;
using std::string;
using std::vector;

class SimpleHttpClient {
private:
    string _host;
    int _port;
    
public:
    SimpleHttpClient(const string& host, int port) : _host(host), _port(port) {}
    
    string sendRequest(const string& method, const string& path, 
                      const string& body = "", const string& contentType = "") {
        // 创建socket
        int sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd == -1) {
            return "ERROR: Failed to create socket";
        }
        
        // 连接服务器
        struct sockaddr_in serverAddr;
        memset(&serverAddr, 0, sizeof(serverAddr));
        serverAddr.sin_family = AF_INET;
        serverAddr.sin_port = htons(_port);
        serverAddr.sin_addr.s_addr = inet_addr(_host.c_str());
        
        if (connect(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
            close(sockfd);
            return "ERROR: Failed to connect to server";
        }
        
        // 构建HTTP请求
        std::ostringstream request;
        request << method << " " << path << " HTTP/1.1\r\n";
        request << "Host: " << _host << ":" << _port << "\r\n";
        request << "User-Agent: SimpleHttpClient/1.0\r\n";
        request << "Connection: close\r\n";
        
        if (!body.empty()) {
            request << "Content-Length: " << body.length() << "\r\n";
            if (!contentType.empty()) {
                request << "Content-Type: " << contentType << "\r\n";
            }
        }
        
        request << "\r\n";
        if (!body.empty()) {
            request << body;
        }
        
        string requestStr = request.str();
        
        // 发送请求
        if (send(sockfd, requestStr.c_str(), requestStr.length(), 0) == -1) {
            close(sockfd);
            return "ERROR: Failed to send request";
        }
        
        // 接收响应
        string response;
        char buffer[4096];
        ssize_t bytesRead;
        
        while ((bytesRead = recv(sockfd, buffer, sizeof(buffer) - 1, 0)) > 0) {
            buffer[bytesRead] = '\0';
            response += buffer;
        }
        
        close(sockfd);
        return response;
    }
    
    string get(const string& path) {
        return sendRequest("GET", path);
    }
    
    string post(const string& path, const string& body, const string& contentType = "application/json") {
        return sendRequest("POST", path, body, contentType);
    }
};

void testBasicRequests() {
    cout << "=== 基础HTTP请求测试 ===" << endl;
    SimpleHttpClient client("127.0.0.1", 8080);
    
    vector<std::pair<string, string>> tests = {
        {"GET /", "主页HTML"},
        {"GET /hello", "Hello World API"},
        {"GET /api/status", "服务器状态"},
        {"GET /user/123", "用户信息"},
        {"GET /api/headers", "请求头信息"},
        {"GET /api/query?name=test&age=25", "查询参数"}
    };
    
    for (const auto& test : tests) {
        cout << "\n--- " << test.second << " ---" << endl;
        cout << "请求: " << test.first << endl;
        
        string response = client.get(test.first.substr(4)); // 去除"GET "
        
        // 只显示响应头和部分响应体
        size_t headerEndPos = response.find("\r\n\r\n");
        if (headerEndPos != string::npos) {
            string headers = response.substr(0, headerEndPos);
            string body = response.substr(headerEndPos + 4);
            
            cout << "响应头:\n" << headers << endl;
            cout << "响应体长度: " << body.length() << " bytes" << endl;
            
            if (body.length() < 200) {
                cout << "响应体:\n" << body << endl;
            } else {
                cout << "响应体: [内容过长，已省略]" << endl;
            }
        } else {
            cout << "响应: " << response << endl;
        }
        
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}

void testPostRequests() {
    cout << "\n=== POST请求测试 ===" << endl;
    SimpleHttpClient client("127.0.0.1", 8080);
    
    vector<std::pair<string, string>> postTests = {
        {"Hello, HTTP Server!", "简单文本"},
        {R"({"name": "test", "value": 42})", "JSON数据"},
        {"name=John&age=30", "表单数据"}
    };
    
    for (const auto& test : postTests) {
        cout << "\n--- POST测试: " << test.second << " ---" << endl;
        cout << "POST数据: " << test.first << endl;
        
        string response = client.post("/api/echo", test.first);
        
        // 只显示响应体
        size_t headerEndPos = response.find("\r\n\r\n");
        if (headerEndPos != string::npos) {
            string body = response.substr(headerEndPos + 4);
            cout << "响应: " << body << endl;
        }
        
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
}

void testConcurrentRequests() {
    cout << "\n=== 并发请求测试 ===" << endl;
    cout << "启动10个并发客户端测试负载均衡..." << endl;
    
    vector<std::thread> threads;
    
    for (int i = 0; i < 10; ++i) {
        threads.emplace_back([i]() {
            SimpleHttpClient client("127.0.0.1", 8080);
            
            for (int j = 0; j < 3; ++j) {
                string path = "/api/status";
                string response = client.get(path);
                
                cout << "线程 " << i << " 请求 " << j << " 完成" << endl;
                std::this_thread::sleep_for(std::chrono::milliseconds(50));
            }
        });
    }
    
    // 等待所有线程完成
    for (auto& t : threads) {
        t.join();
    }
    
    cout << "并发测试完成" << endl;
}

void testErrorHandling() {
    cout << "\n=== 错误处理测试 ===" << endl;
    SimpleHttpClient client("127.0.0.1", 8080);
    
    vector<std::pair<string, string>> errorTests = {
        {"/notfound", "404 Not Found"},
        {"/api/badpath", "404 Not Found"}
    };
    
    for (const auto& test : errorTests) {
        cout << "\n--- " << test.second << " ---" << endl;
        string response = client.get(test.first);
        
        // 只显示状态行和响应体
        size_t firstLineEnd = response.find('\r');
        if (firstLineEnd != string::npos) {
            cout << "状态: " << response.substr(0, firstLineEnd) << endl;
        }
        
        size_t headerEndPos = response.find("\r\n\r\n");
        if (headerEndPos != string::npos) {
            string body = response.substr(headerEndPos + 4);
            cout << "错误信息: " << body << endl;
        }
    }
}

int main() {
    cout << "HTTP服务器客户端测试工具" << endl;
    cout << "目标服务器: http://127.0.0.1:8080" << endl;
    cout << "请确保HTTP服务器正在运行..." << endl;
    
    // 等待一下让用户准备
    std::this_thread::sleep_for(std::chrono::seconds(1));
    
    try {
        // 基础请求测试
        testBasicRequests();
        
        // POST请求测试  
        testPostRequests();
        
        // 并发请求测试
        testConcurrentRequests();
        
        // 错误处理测试
        testErrorHandling();
        
        cout << "\n=== 测试完成 ===" << endl;
        cout << "所有HTTP功能测试已完成！" << endl;
        
    } catch (const std::exception& e) {
        cout << "测试过程中发生错误: " << e.what() << endl;
    }
    
    return 0;
}